home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / borland / jnfb88.zip / EXPWLD.ZIP / SETARGV.ASM < prev    next >
Assembly Source File  |  1987-08-18  |  14KB  |  412 lines

  1.         NAME    setargv
  2.         PAGE    60,132
  3. ;[]------------------------------------------------------------[]
  4. ;|      SETARGV.ASM -- Parse Command Line                       |
  5. ;|                                                              |
  6. ;|      Turbo-C Run Time Library        version 1.0             |
  7. ;|                                                              |
  8. ;|      Copyright (c) 1987 by Borland International Inc.        |
  9. ;|      All Rights Reserved.                                    |
  10. ;[]------------------------------------------------------------[]
  11.  
  12.         INCLUDE RULES.ASI
  13.  
  14. ;       Segment and Group declarations
  15.  
  16. Header@
  17.  
  18. ;       External references
  19.  
  20. ExtSym@         __argc, WORD, __CDECL__
  21. dPtrExt@        __argv, __CDECL__
  22. ExtSym@         _psp, WORD, __CDECL__
  23. ExtSym@         _envseg, WORD, __CDECL__
  24. ExtSym@         _envLng, WORD, __CDECL__
  25. ExtSym@         _osmajor, BYTE, __CDECL__
  26. ExtProc@        abort, __CDECL__
  27.  
  28. ;*** Begin addition
  29. ; Here we declare our new C routine, expwild, as well as the fact 
  30. ; that we will use the library routine sbrk (for memory allocation). 
  31. ; We also need to know the size of the stack, and so access it.  
  32. ; The macros ExtProc and ExtSym are defined in RULES.ASI.
  33. ;
  34. ExtProc@        expwild, __CDECL__
  35. ExtProc@        sbrk, __CDECL__
  36. ExtSym@         _stklen, WORD, __CDECL__
  37. ;
  38. ;*** End addition
  39.  
  40.  
  41.         SUBTTL  Parse Command Line
  42.         PAGE
  43. ;/*                                                     */
  44. ;/*-----------------------------------------------------*/
  45. ;/*                                                     */
  46. ;/*     Parse Command Line                              */
  47. ;/*     ------------------                              */
  48. ;/*                                                     */
  49. ;/*-----------------------------------------------------*/
  50. ;/*                                                     */
  51. PSPCmd          equ     00080h
  52.  
  53.  
  54. CSeg@
  55.  
  56. IF      LPROG
  57. SavedReturn     dd      ?
  58. ELSE
  59. SavedReturn     dw      ?
  60. ENDIF
  61. SavedDS         dw      ?
  62. SavedBP         dw      ?
  63.  
  64. ;*** Begin addition
  65. ; Here we declare a double word pointer to hold the address of our 
  66. ; command line string and a word to hold the string's size.  We 
  67. ; do not initialize either one.  
  68. ;
  69. NewCmdLn        dd      ?
  70. NewCmdSz        dw      ?
  71. ;
  72. ;*** End addition
  73.  
  74. PubProc@        _setargv, __CDECL__
  75.  
  76. ;       First, save caller context and Return Address
  77.  
  78.         pop     word ptr SavedReturn
  79. IF      LPROG
  80.         pop     word ptr SavedReturn+2
  81. ENDIF
  82.         mov     SavedDS, ds
  83.  
  84. ;*** Begin deletion
  85. ; This block of code got the address of the command line, zeroed 
  86. ; the registers, got the command line's length, appended a null to 
  87. ; the command line, and set up the registers for later.  cx ended 
  88. ; up containing the size of the command line string, including the 
  89. ; null, and other registers were set to zero.  The code we give 
  90. ; below to replace this code will end up in the same state, but will 
  91. ; first call our routine expwild to preprocess the command line.  
  92. ;
  93. ;       cld
  94. ;       mov     es, _psp@
  95. ;       mov     si, PSPCmd      ; ES: SI = Command Line address
  96. ;       xor     ax, ax
  97. ;       mov     bx, ax
  98. ;       mov     dx, ax          ; AX = BX = CX = DX = 0
  99. ;       mov     cx, ax          ; AX = BX = CX = DX = 0
  100. ;       lods    byte ptr es:[si]
  101. ;       mov     di, si
  102. ;       xchg    ax, bx
  103. ;       mov     es:[di+bx], al  ; Append a \0 at the end
  104. ;       inc     bx
  105. ;       xchg    bx, cx          ; CX = Command Line size including \0
  106. ;
  107. ;*** End deletion
  108.  
  109. ;*** Begin addition
  110. ; Preprocess the command line for wild card expansion
  111. ;
  112. ; First, we get the stack size to see how large the expanded text 
  113. ; can be.  We limit ourselves to one-half of the available stack.  
  114.  
  115. IFDEF   __HUGE__
  116.         mov     ax, seg _stklen@   ; if we are using the huge model,
  117.         mov     es, ax             ; we need the segment that holds 
  118.         mov     ax, es:_stklen@    ; the stack data
  119. ELSE
  120.         mov     ax, _stklen@       ; here we need only the stack's 
  121.                                    ; length, as all data in one seg
  122. ENDIF
  123.         sar     ax, 1           ; Divide by two to leave room
  124.  
  125.         mov     NewCmdSz, ax    ; Save the maximum command size
  126.  
  127. ; Now we call sbrk to allocate the desired memory.  We push the 
  128. ; amount we need, which was in ax, onto the stack and do the call.  
  129.  
  130.         push    ax
  131.         call    sbrk@           ; Get some memory
  132.  
  133. ; After a call we must restore the stack to its previous state.  
  134. ; Rather than popping the argument we just adjust the stack pointer.
  135. ; Also, because we called a C routine, which could have messed up 
  136. ; our data segment, we restore it to the segment value saved earlier 
  137. ; by the existing code.  Finally, we save the address of the new 
  138. ; command line buffer we allocated, which was returned in ax.  
  139.  
  140.         add     sp, 2           ; Clean up the stack
  141.         mov     ds, SavedDS     ; Necessary?
  142.         mov     word ptr NewCmdLn, ax   ; Save the pointer offset
  143.  
  144. ; sbrk returns the segment in dx for large memory model code. 
  145. ; So, if we're not using that model, set dx to our segment so that 
  146. ; the following code will work.  
  147.  
  148. IFE     LDATA
  149.         mov     dx, ds          ; Get our own segment if not returned
  150. ENDIF
  151.         mov     word ptr NewCmdLn+2, dx ; Save the pointer offset 
  152.                                         ; segment just after the 
  153.                                         ; pointer offset
  154.         cld                     ; tell it to increment pointers 
  155.                                 ; after string operations
  156.  
  157. ; Now we do basically what the earlier deleted code did.  We get 
  158. ; the command line address and append a null to the command line. 
  159.  
  160.         mov     es, _psp@       ; Get the DOS command line
  161.         mov     si, PSPCmd      ;  address
  162.         xor     ax, ax          ; Zero AX and BX
  163.         mov     bx, ax
  164.         lods    byte ptr es:[si]
  165.         xchg    ax, bx
  166.         mov     es:[si+bx], al  ; Append a \0 at the end
  167.  
  168. ; Here we push the arguments for expwild and then make the call.  
  169. ; The third arg, and so the first to be pushed, is the maximum 
  170. ; command line size.
  171.  
  172.         mov     ax, NewCmdSz    ; Get the maximum command size
  173.         push    ax
  174.  
  175. ; The second arg is the destination string.  We push first its 
  176. ; segment if we are in large model.  In any case, we then push its 
  177. ; offset.  
  178.  
  179. IF LDATA
  180.         mov     ax, word ptr NewCmdLn+2 ; Segment for large data
  181.         push    ax
  182. ENDIF
  183.         mov     ax, word ptr NewCmdLn   ; Destination offset
  184.         push    ax
  185.  
  186. ; The first arg is the source command line string.  We push both its 
  187. ; segment and offset in all cases because expwild expects a far ptr
  188. ; for this arg.  
  189.  
  190.         mov     ax, _psp@       ; Segment of DOS command line
  191.         push    ax
  192.         mov     ax, PSPCmd+1    ; Offset (+ 1 to pass the count byte)
  193.         push    ax
  194.         call    expwild@        ; Finally, call expwild to expand 
  195.                                 ; the command line
  196.  
  197. ; Clean up the stack after the call.  We adjust by 10 if in large 
  198. ; model because of the extra segment id we pushed.  
  199.  
  200. IF LDATA
  201.         add     sp, 10          ; Clean up the stack
  202. ELSE
  203.         add     sp, 8           ; Clean up the stack
  204. ENDIF
  205.         mov     ds, SavedDS     ; Restore our data segment
  206.  
  207. ; Then, process the command line.  We put the size in cx and the 
  208. ; string itself in es:[si], just as their code did.  Finally, we 
  209. ; zero the same registers as the original (now deleted) code.  
  210.  
  211.         mov     cx, ax          ; Put size in CX
  212.         mov     es, word ptr NewCmdLn+2
  213.         mov     si, word ptr NewCmdLn   ; Get the address of the 
  214.                                         ; expanded string
  215.         mov     di, si          ; Set up the registers correctly
  216.         xor     ax, ax          ; AX = BX = CX = DX = 0
  217.         mov     bx, ax
  218.         mov     dx, ax
  219. ;
  220. ;*** End addition
  221.  
  222. Processing      label   near
  223.         call    NextChar
  224.         ja